# Process this file with autoconf to produce a configure script.

AC_INIT(inetd/inetd.c)

AC_CONFIG_HEADER(include/config.h:headers/config.h.in)

# These lists don't contain talk or talkd, which will get added later if nec.
COMMON='libtelnet libinetutils'
SERVERS='inetd ftpd telnetd rshd rlogind uucpd rexecd syslogd tftpd'
CLIENTS='telnet ftp rsh rcp rlogin tftp syslog'
AC_SUBST(COMMON)
AC_SUBST(SERVERS)
AC_SUBST(CLIENTS)

# All subdirectories, whether built or not
SUBDIRS="headers $SERVERS $CLIENTS $COMMON"
AC_SUBST(SUBDIRS)

# Optional things we put into libinetutils (we use the name `LIBOBJS' because
# that's what AC_REPLACE_FUNCS uses).
LIBOBJS=''
AC_SUBST(LIBOBJS)

# Include files that we link into our own include directory from headers.
# Initialize it with the things we always want to use.
INCLUDES="version.h crypt.h arpa/telnet.h arpa/ftp.h arpa/tftp.h"

AC_ARG_ENABLE(encryption, [  --enable-encryption     enable encryption],
	      , enable_encryption=no)
AC_ARG_ENABLE(authentication,
	      [  --enable-authentication enable connection authentication],
	      , enable_authentication=no)
# By default we compile both servers and clients, but see what the user wants
AC_ARG_ENABLE(servers, [  --disable-servers       don't compile servers],
	      , enable_servers=yes)
AC_ARG_ENABLE(clients, [  --disable-clients       don't compile clients],
	      , enable_clients=yes)

AC_ARG_ENABLE(talk,    [  --disable-talk          don't compile talk or talkd],
              , enable_talk=maybe)

AC_PROG_MAKE_SET

AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_YACC
AC_CHECK_TOOL(AR, ar)
AC_CHECK_TOOL(RANLIB, ranlib, :)
AC_PATH_PROG(RM, rm, rm)

AC_CHECK_HEADERS(malloc.h errno.h string.h stdarg.h termio.h termios.h \
		 stdlib.h sys/tty.h sys/utsname.h \
		 sys/msgbuf.h krb.h des.h netinet/in_systm.h \
		 netinet/ip.h netinet/ip_icmp.h netinet/ip_var.h vis.h \
		 sys/ioctl_compat.h sys/cdefs.h)

# Headers that we use our own version of if the system doesn't have them.
AC_CHECK_HEADER(paths.h, , INCLUDES="$INCLUDES paths.h")

AC_CHECK_LIB(util, logout, LIBUTIL=-lutil)
AC_SUBST(LIBUTIL)
AC_CHECK_LIB(crypt, crypt, LIBCRYPT=-lcrypt)
AC_SUBST(LIBCRYPT)

if test "$enable_encryption" = yes -o "$enable_authentication" = yes; then
  AC_CHECK_LIB(krb, krb_mk_req, LIBAUTH=-lkrb)
  AC_CHECK_LIB(des, des_key_sched, LIBAUTH="$LIBAUTH -ldes")
  AC_SUBST(LIBAUTH)
fi

_SAVE_LIBS="$LIBS"
LIBS="$LIBUTIL $LIBS"
AC_CHECK_FUNCS(cgetent uname strdup setutent_r logwtmp fpathconf tcgetattr crypt)
LIBS="$_SAVE_LIBS"

# If there's no libtermcap, add a bogus version of tgetent to libinetutils,
# as that's the only function actually used (except for dependencies from
# curses).
AC_CHECK_LIB(termcap, tgetent, LIBTERMCAP=-ltermcap)
if test "$ac_cv_lib_termcap_tgetent" = no; then
  AC_CHECK_LIB(termlib, tgetent, LIBTERMCAP=-ltermlib)
fi
AC_SUBST(LIBTERMCAP)

if test -z "$LIBTERMCAP"; then
  # Some packages include termcap just to check terminal type validity;
  # for those cases, we really don't need termcap.
  LIBOBJS="$LIBOBJS stub_tgetent.o"
fi

# Only talk uses curses
if test "$enable_talk" != no; then
  _SAVE_LIBS="$LIBS"
  LIBS="$LIBTERMCAP"
  AC_CHECK_LIB(curses, initscr, LIBCURSES="-lcurses")
  if test "$LIBCURSES" -a "$LIBTERMCAP"; then
    AC_CACHE_CHECK(whether curses needs $LIBTERMCAP,
		   inetutils_cv_curses_needs_termcap,
      LIBS="$LIBCURSES"
      AC_TRY_LINK([#include <curses.h>], [initscr ();],
		  [inetutils_cv_curses_needs_termcap=no],
		  [inetutils_cv_curses_needs_termcap=yes]))
  fi
  LIBS="$_SAVE_LIBS"
fi
AC_SUBST(LIBCURSES)

AC_TYPE_SIGNAL

# Use `setpgid' if it's around, otherwise assume a BSD setpgrp
AC_CHECK_FUNC(setpgid, , AC_DEFINE(setpgid, setpgrp))

if test "$enable_talk" = maybe; then
  enable_talk=$ac_cv_lib_curses_initscr
fi

AC_CACHE_CHECK(for EWOULDBLOCK in <errno.h>, inetutils_cv_macro_ewouldblock,
AC_EGREP_CPP(HAVE_EWOULDBLOCK,
[#include <errno.h>
#ifdef EWOULDBLOCK
HAVE_EWOULDBLOCK
#endif],
  [inetutils_cv_macro_ewouldblock=yes],
  [inetutils_cv_macro_ewouldblock=no]))
if test "$inetutils_cv_macro_ewouldblock" = no; then
  AC_DEFINE(EWOULDBLOCK,EAGAIN)
fi

AC_CACHE_CHECK(for __P, inetutils_cv_macro___p,
AC_EGREP_CPP(HAVE___P,
[#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
#ifdef __P
HAVE___P
#endif],
  [inetutils_cv_macro___p=yes],
  [inetutils_cv_macro___p=no]))
if test "$inetutils_cv_macro___p" = yes; then
  AC_DEFINE(HAVE___P)
fi

# This can't just be a compile-check, as gcc somtimes accepts the syntax even
# if feature isn't actually supported.
AC_CACHE_CHECK(whether gcc weak references work,
	       inetutils_cv_weak_refs,
AC_TRY_LINK([],
  [extern char *not_defined (char *, char *) __attribute__ ((weak));
   if (not_defined) puts ("yes"); ],
  [inetutils_cv_weak_refs=yes],
  [inetutils_cv_weak_refs=no]))
if test "$inetutils_cv_weak_refs" = yes; then
  AC_DEFINE(HAVE_WEAK_REFS)
else
  AC_CACHE_CHECK(whether pragma weak references work,
		 inetutils_cv_pragma_weak_refs,
  AC_TRY_LINK([],
    [extern char *not_defined (char *, char *);
#pragma weak not_defined
     if (not_defined) puts ("yes"); ],
    [inetutils_cv_pragma_weak_refs=yes],
    [inetutils_cv_pragma_weak_refs=no]))
  if test "$inetutils_cv_pragma_weak_refs" = yes; then
    AC_DEFINE(HAVE_PRAGMA_WEAK_REFS)
  else
    AC_CACHE_CHECK(whether asm weak references work,
		   inetutils_cv_asm_weak_refs,
    AC_TRY_LINK([],
      [extern char *not_defined (char *, char *);
       asm (".weak not_defined");
       if (not_defined) puts ("yes"); ],
      [inetutils_cv_asm_weak_refs=yes],
      [inetutils_cv_asm_weak_refs=no]))
    if test "$inetutils_cv_asm_weak_refs" = yes; then
      AC_DEFINE(HAVE_ASM_WEAK_REFS)
    fi
  fi
fi

AC_CACHE_CHECK(whether struct stat has timespec fields,
	       inetutils_cv_struct_st_timespec,
AC_TRY_COMPILE(
[#include <sys/types.h>
#include <sys/stat.h>],
  [struct stat st; st.st_mtimespec.ts_nsec = 0;],
  [inetutils_cv_struct_st_timespec=yes],
  [inetutils_cv_struct_st_timespec=no]))
if test "$inetutils_cv_struct_st_timespec" = yes; then
  AC_DEFINE(HAVE___P)
fi

if test "$inetutils_cv_struct_st_timespec" = yes; then
  AC_DEFINE(HAVE_ST_TIMESPEC)
else
  AC_CACHE_CHECK(whether struct stat has time_usec fields,
		 inetutils_cv_struct_st_time_usec,
  AC_TRY_COMPILE(
[#include <sys/types.h>
#include <sys/stat.h>],
    [struct stat st; st.st_mtime_usec = 0;],
    [inetutils_cv_struct_st_time_usec=yes],
    [inetutils_cv_struct_st_time_usec=no]))

  if test "$inetutils_cv_struct_st_time_usec" = yes; then
    AC_DEFINE(HAVE_ST_TIME_USEC)
  fi
fi

if test "$enable_talk" = yes; then
  SERVERS="$SERVERS talkd"
  CLIENTS="$CLIENTS talk"

  AC_CACHE_CHECK(for struct osockaddr in <sys/socket.h>,
		 inetutils_cv_struct_osockaddr,
  AC_TRY_COMPILE(
[#include <sys/types.h>
#include <sys/socket.h>],
    [struct osockaddr sa;],
    [inetutils_cv_struct_osockaddr=yes],
    [inetutils_cv_struct_osockaddr=no]))

  if test "$inetutils_cv_struct_osockaddr" = yes; then
    AC_DEFINE(HAVE_OSOCKADDR)
  else
    # Use our own definition
    INCLUDES="$INCLUDES osockaddr.h"
  fi
fi
# Update SUBDIRS regardless
SUBDIRS="$SUBDIRS talkd talk"

SERVERS_OR_CLIENTS=
if test "$enable_servers" = yes; then
  SERVERS_OR_CLIENTS="$SERVERS"
fi
if test "$enable_clients" = yes; then
  SERVERS_OR_CLIENTS="$SERVERS_OR_CLIENTS $CLIENTS"
fi
AC_SUBST(SERVERS_OR_CLIENTS)

if test "$enable_authentication" = yes; then
  AC_DEFINE(AUTHENTICATION)
fi
if test "$enable_encryption" = yes; then
  AC_DEFINE(ENCRYPTION)
fi

if test "$enable_authentication" = yes -a "$ac_cv_lib_krb_krb_mk_req" = yes; then
  AC_DEFINE(KRB4)
fi
if test "$enable_encryption" = yes -a "$ac_cv_lib_des_des_key_sched" = yes; then
  AC_DEFINE(DES_ENCRYPTION)
fi

# We use our own version of getopt if the system one doesn't have getopt_long
AC_CHECK_FUNC(getopt_long, ,
  INCLUDES="$INCLUDES getopt.h"
  LIBOBJS="$LIBOBJS getopt.o getopt1.o")

# Supply versions of the BSD error reporting functions if the system doesn't
AC_CHECK_FUNC(verrx, ,
  INCLUDES="$INCLUDES err.h"
  LIBOBJS="$LIBOBJS err.o")

# See if the system has strerror, and replace it if not
AC_CHECK_FUNC(strerror, , LIBOBJS="$LIBOBJS strerror.o")
if test "$ac_cv_func_strerror" = no; then
  # No strerror, so see if the SYS_ERRLIST variable can be used by ours
  AC_CHECK_FUNC(sys_errlist)
  if test "$ac_cv_func_sys_errlist" = yes; then
    AC_CACHE_CHECK(whether sys_errlist is declared,
 		   inetutils_cv_sys_errlist_decl,
    AC_TRY_COMPILE(
[#include <stdio.h>
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif],
      [char *x = sys_errlist[sys_nerrs - 1];],
      [inetutils_cv_sys_errlist_decl=yes],
      [inetutils_cv_sys_errlist_decl=no]))
    if test "$inetutils_cv_sys_errlist_decl" = yes; then
      AC_DEFINE(HAVE_SYS_ERRLIST_DECL)
    fi
  fi
fi

AC_CACHE_CHECK(for sig_t, inetutils_cv_type_sig_t,
  AC_TRY_COMPILE(
[#include <sys/types.h>
#include <signal.h>],
    [sig_t foo;],
    [inetutils_cv_type_sig_t=yes], [inetutils_cv_type_sig_t=no]))
if test "$inetutils_cv_type_sig_t" = yes; then
  AC_DEFINE(HAVE_SIG_T)
fi

# See if the __PROGNAME variable is defined, otherwise use our own.
AC_CHECK_FUNC(__progname,
  AC_DEFINE(HAVE___PROGNAME),
  LIBOBJS="$LIBOBJS __progname.o")

# See if snprintf exists, otherwise just use a bogus version
AC_CHECK_FUNC(snprintf,
  AC_DEFINE(HAVE_SNPRINTF),
  LIBOBJS="$LIBOBJS snprintf.o")

# Supply optional header files by linking a copy into the object include dir
_ISRCS="`for I in $INCLUDES; do echo $ac_n ' 'headers/$I$ac_c; done`"
_IDSTS="`for I in $INCLUDES; do echo $ac_n ' 'include/$I$ac_c; done`"
AC_LINK_FILES($_ISRCS, $_IDSTS)

SUBDIR_MAKEFILES="`for D in $SUBDIRS; do echo $ac_n ' '$D/Makefile$ac_c; done`"
AC_OUTPUT(Makefile config.make $SUBDIR_MAKEFILES)
